home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2005 March / Macworld CD March 2005 - Marathon Trilogy.iso / Shareware World / iPod / iPodderX.sit / iPodderX / iPodderX.app / Contents / Resources / Downloader.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2005-01-07  |  23.8 KB  |  807 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.3)
  3.  
  4. from CurrentRateMeasure import Measure
  5. from random import shuffle
  6. from time import time
  7. from bitfield import Bitfield
  8.  
  9. class SingleDownload:
  10.     
  11.     def __init__(self, downloader, connection):
  12.         self.downloader = downloader
  13.         self.connection = connection
  14.         self.choked = True
  15.         self.interested = False
  16.         self.active_requests = []
  17.         self.measure = Measure(downloader.max_rate_period)
  18.         self.have = Bitfield(downloader.numpieces)
  19.         self.last = 0
  20.         self.example_interest = None
  21.  
  22.     
  23.     def disconnected(self):
  24.         self.downloader.downloads.remove(self)
  25.         for i in xrange(len(self.have)):
  26.             if self.have[i]:
  27.                 self.downloader.picker.lost_have(i)
  28.                 continue
  29.         
  30.         self._letgo()
  31.  
  32.     
  33.     def _letgo(self):
  34.         if not (self.active_requests):
  35.             return None
  36.         
  37.         if self.downloader.storage.is_endgame():
  38.             self.active_requests = []
  39.             return None
  40.         
  41.         lost = []
  42.         for index, begin, length in self.active_requests:
  43.             self.downloader.storage.request_lost(index, begin, length)
  44.             if index not in lost:
  45.                 lost.append(index)
  46.                 continue
  47.         
  48.         self.active_requests = []
  49.         ds = []
  50.         shuffle(ds)
  51.         for d in ds:
  52.             d._request_more(lost)
  53.         
  54.         for d in self.downloader.downloads:
  55.             if d.choked and not (d.interested):
  56.                 for l in lost:
  57.                     if d.have[l] and self.downloader.storage.do_I_have_requests(l):
  58.                         d.interested = True
  59.                         d.connection.send_interested()
  60.                         break
  61.                         continue
  62.                 
  63.         
  64.  
  65.     
  66.     def got_choke(self):
  67.         if not (self.choked):
  68.             self.choked = True
  69.             self._letgo()
  70.         
  71.  
  72.     
  73.     def got_unchoke(self):
  74.         if self.choked:
  75.             self.choked = False
  76.             if self.interested:
  77.                 self._request_more()
  78.             
  79.         
  80.  
  81.     
  82.     def is_choked(self):
  83.         return self.choked
  84.  
  85.     
  86.     def is_interested(self):
  87.         return self.interested
  88.  
  89.     
  90.     def got_piece(self, index, begin, piece):
  91.         
  92.         try:
  93.             self.active_requests.remove((index, begin, len(piece)))
  94.         except ValueError:
  95.             return False
  96.  
  97.         if self.downloader.storage.is_endgame():
  98.             self.downloader.all_requests.remove((index, begin, len(piece)))
  99.         
  100.         self.last = time()
  101.         self.measure.update_rate(len(piece))
  102.         self.downloader.measurefunc(len(piece))
  103.         self.downloader.downmeasure.update_rate(len(piece))
  104.         if not self.downloader.storage.piece_came_in(index, begin, piece):
  105.             if self.downloader.storage.is_endgame():
  106.                 while self.downloader.storage.do_I_have_requests(index):
  107.                     (nb, nl) = self.downloader.storage.new_request(index)
  108.                     self.downloader.all_requests.append((index, nb, nl))
  109.                 for d in self.downloader.downloads:
  110.                     d.fix_download_endgame()
  111.                 
  112.                 return False
  113.             
  114.             self.downloader.picker.bump(index)
  115.             ds = []
  116.             shuffle(ds)
  117.             for d in ds:
  118.                 d._request_more([
  119.                     index])
  120.             
  121.             return False
  122.         
  123.         if self.downloader.storage.do_I_have(index):
  124.             self.downloader.picker.complete(index)
  125.         
  126.         if self.downloader.storage.is_endgame():
  127.             for d in self.downloader.downloads:
  128.                 if d is not self and d.interested:
  129.                     if d.choked:
  130.                         d.fix_download_endgame()
  131.                     else:
  132.                         
  133.                         try:
  134.                             d.active_requests.remove((index, begin, len(piece)))
  135.                         except ValueError:
  136.                             continue
  137.  
  138.                         d.connection.send_cancel(index, begin, len(piece))
  139.                         d.fix_download_endgame()
  140.                 d.choked
  141.             
  142.         
  143.         self._request_more()
  144.         if self.downloader.picker.am_I_complete():
  145.             for i in self.downloader.downloads:
  146.                 if i.have.numfalse == 0:
  147.                     _[1](i)
  148.                     continue
  149.                 []
  150.             
  151.         
  152.         return self.downloader.storage.do_I_have(index)
  153.  
  154.     
  155.     def _want(self, index):
  156.         if self.have[index]:
  157.             pass
  158.         return self.downloader.storage.do_I_have_requests(index)
  159.  
  160.     
  161.     def _request_more(self, indices = None):
  162.         if not not (self.choked):
  163.             raise AssertionError
  164.         if len(self.active_requests) == self.downloader.backlog:
  165.             return None
  166.         
  167.         if self.downloader.storage.is_endgame():
  168.             self.fix_download_endgame()
  169.             return None
  170.         
  171.         lost_interests = []
  172.         while len(self.active_requests) < self.downloader.backlog:
  173.             if indices is None:
  174.                 interest = self.downloader.picker.next(self._want, self.have.numfalse == 0)
  175.             else:
  176.                 interest = None
  177.                 for i in indices:
  178.                     if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  179.                         interest = i
  180.                         break
  181.                         continue
  182.                 
  183.             if interest is None:
  184.                 break
  185.             
  186.             if not (self.interested):
  187.                 self.interested = True
  188.                 self.connection.send_interested()
  189.             
  190.             self.example_interest = interest
  191.             (begin, length) = self.downloader.storage.new_request(interest)
  192.             self.downloader.picker.requested(interest, self.have.numfalse == 0)
  193.             self.active_requests.append((interest, begin, length))
  194.             self.connection.send_request(interest, begin, length)
  195.             if not self.downloader.storage.do_I_have_requests(interest):
  196.                 lost_interests.append(interest)
  197.                 continue
  198.         if not (self.active_requests) and self.interested:
  199.             self.interested = False
  200.             self.connection.send_not_interested()
  201.         
  202.         if lost_interests:
  203.             for d in self.downloader.downloads:
  204.                 if d.active_requests or not (d.interested):
  205.                     continue
  206.                 
  207.                 if d.example_interest is not None and self.downloader.storage.do_I_have_requests(d.example_interest):
  208.                     continue
  209.                 
  210.                 for lost in lost_interests:
  211.                     if d.have[lost]:
  212.                         break
  213.                         continue
  214.                 
  215.                 interest = self.downloader.picker.next(d._want, d.have.numfalse == 0)
  216.                 if interest is None:
  217.                     d.interested = False
  218.                     d.connection.send_not_interested()
  219.                     continue
  220.                 d.example_interest = interest
  221.             
  222.         
  223.         if self.downloader.storage.is_endgame():
  224.             self.downloader.all_requests = []
  225.             for d in self.downloader.downloads:
  226.                 self.downloader.all_requests.extend(d.active_requests)
  227.             
  228.             for d in self.downloader.downloads:
  229.                 d.fix_download_endgame()
  230.             
  231.         
  232.  
  233.     
  234.     def fix_download_endgame(self):
  235.         want = []
  236.         if self.interested and not (self.active_requests) and not want:
  237.             self.interested = False
  238.             self.connection.send_not_interested()
  239.             return None
  240.         
  241.         if not (self.interested) and want:
  242.             self.interested = True
  243.             self.connection.send_interested()
  244.         
  245.         if self.choked:
  246.             return None
  247.         
  248.         shuffle(want)
  249.         del want[self.downloader.backlog - len(self.active_requests):]
  250.         self.active_requests.extend(want)
  251.         for piece, begin, length in want:
  252.             self.connection.send_request(piece, begin, length)
  253.         
  254.  
  255.     
  256.     def got_have(self, index):
  257.         if self.have[index]:
  258.             return None
  259.         
  260.         self.have[index] = True
  261.         self.downloader.picker.got_have(index)
  262.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  263.             self.connection.close()
  264.             return None
  265.         
  266.         if self.downloader.storage.is_endgame():
  267.             self.fix_download_endgame()
  268.         elif self.downloader.storage.do_I_have_requests(index):
  269.             if not (self.choked):
  270.                 self._request_more([
  271.                     index])
  272.             elif not (self.interested):
  273.                 self.interested = True
  274.                 self.connection.send_interested()
  275.             
  276.         
  277.  
  278.     
  279.     def got_have_bitfield(self, have):
  280.         self.have = have
  281.         for i in xrange(len(self.have)):
  282.             if self.have[i]:
  283.                 self.downloader.picker.got_have(i)
  284.                 continue
  285.         
  286.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  287.             self.connection.close()
  288.             return None
  289.         
  290.         if self.downloader.storage.is_endgame():
  291.             for piece, begin, length in self.downloader.all_requests:
  292.                 if self.have[piece]:
  293.                     self.interested = True
  294.                     self.connection.send_interested()
  295.                     return None
  296.                     continue
  297.             
  298.         
  299.         for i in xrange(len(self.have)):
  300.             if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  301.                 self.interested = True
  302.                 self.connection.send_interested()
  303.                 return None
  304.                 continue
  305.         
  306.  
  307.     
  308.     def get_rate(self):
  309.         return self.measure.get_rate()
  310.  
  311.     
  312.     def is_snubbed(self):
  313.         return time() - self.last > self.downloader.snub_time
  314.  
  315.  
  316.  
  317. class Downloader:
  318.     
  319.     def __init__(self, storage, picker, backlog, max_rate_period, numpieces, downmeasure, snub_time, measurefunc = (lambda x: None)):
  320.         self.storage = storage
  321.         self.picker = picker
  322.         self.backlog = backlog
  323.         self.max_rate_period = max_rate_period
  324.         self.downmeasure = downmeasure
  325.         self.numpieces = numpieces
  326.         self.snub_time = snub_time
  327.         self.measurefunc = measurefunc
  328.         self.downloads = []
  329.  
  330.     
  331.     def make_download(self, connection):
  332.         self.downloads.append(SingleDownload(self, connection))
  333.         return self.downloads[-1]
  334.  
  335.  
  336.  
  337. class DummyPicker:
  338.     
  339.     def __init__(self, num, r):
  340.         self.stuff = range(num)
  341.         self.r = r
  342.  
  343.     
  344.     def next(self, wantfunc, seed):
  345.         for i in self.stuff:
  346.             if wantfunc(i):
  347.                 return i
  348.                 continue
  349.         
  350.         return None
  351.  
  352.     
  353.     def lost_have(self, pos):
  354.         self.r.append('lost have')
  355.  
  356.     
  357.     def got_have(self, pos):
  358.         self.r.append('got have')
  359.  
  360.     
  361.     def requested(self, pos, seed):
  362.         self.r.append('requested')
  363.  
  364.     
  365.     def complete(self, pos):
  366.         self.stuff.remove(pos)
  367.         self.r.append('complete')
  368.  
  369.     
  370.     def am_I_complete(self):
  371.         return False
  372.  
  373.     
  374.     def bump(self, i):
  375.         pass
  376.  
  377.  
  378.  
  379. class DummyStorage:
  380.     
  381.     def __init__(self, remaining, have_endgame = False, numpieces = 1):
  382.         self.remaining = remaining
  383.         self.active = [ [] for i in xrange(numpieces) ]
  384.         self.endgame = False
  385.         self.have_endgame = have_endgame
  386.  
  387.     
  388.     def do_I_have_requests(self, index):
  389.         return self.remaining[index] != []
  390.  
  391.     
  392.     def request_lost(self, index, begin, length):
  393.         x = (begin, length)
  394.         self.active[index].remove(x)
  395.         self.remaining[index].append(x)
  396.         self.remaining[index].sort()
  397.  
  398.     
  399.     def piece_came_in(self, index, begin, piece):
  400.         self.active[index].remove((begin, len(piece)))
  401.         return True
  402.  
  403.     
  404.     def do_I_have(self, index):
  405.         if self.remaining[index] == []:
  406.             pass
  407.         return self.active[index] == []
  408.  
  409.     
  410.     def new_request(self, index):
  411.         x = self.remaining[index].pop()
  412.         for i in self.remaining:
  413.             if i:
  414.                 break
  415.                 continue
  416.         else:
  417.             self.endgame = True
  418.         self.active[index].append(x)
  419.         self.active[index].sort()
  420.         return x
  421.  
  422.     
  423.     def is_endgame(self):
  424.         if self.have_endgame:
  425.             pass
  426.         return self.endgame
  427.  
  428.  
  429.  
  430. class DummyConnection:
  431.     
  432.     def __init__(self, events):
  433.         self.events = events
  434.  
  435.     
  436.     def send_interested(self):
  437.         self.events.append('interested')
  438.  
  439.     
  440.     def send_not_interested(self):
  441.         self.events.append('not interested')
  442.  
  443.     
  444.     def send_request(self, index, begin, length):
  445.         self.events.append(('request', index, begin, length))
  446.  
  447.     
  448.     def send_cancel(self, index, begin, length):
  449.         self.events.append(('cancel', index, begin, length))
  450.  
  451.  
  452.  
  453. def test_stops_at_backlog():
  454.     ds = DummyStorage([
  455.         [
  456.             (0, 2),
  457.             (2, 2),
  458.             (4, 2),
  459.             (6, 2)]])
  460.     events = []
  461.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  462.     sd = d.make_download(DummyConnection(events))
  463.     if not events == []:
  464.         raise AssertionError
  465.     if not ds.remaining == [
  466.         [
  467.             (0, 2),
  468.             (2, 2),
  469.             (4, 2),
  470.             (6, 2)]]:
  471.         raise AssertionError
  472.     if not ds.active == [
  473.         []]:
  474.         raise AssertionError
  475.     sd.got_have_bitfield(Bitfield(1, chr(128)))
  476.     if not events == [
  477.         'got have',
  478.         'interested']:
  479.         raise AssertionError
  480.     del events[:]
  481.     if not ds.remaining == [
  482.         [
  483.             (0, 2),
  484.             (2, 2),
  485.             (4, 2),
  486.             (6, 2)]]:
  487.         raise AssertionError
  488.     if not ds.active == [
  489.         []]:
  490.         raise AssertionError
  491.     sd.got_unchoke()
  492.     if not events == [
  493.         'requested',
  494.         ('request', 0, 6, 2),
  495.         'requested',
  496.         ('request', 0, 4, 2)]:
  497.         raise AssertionError
  498.     del events[:]
  499.     if not ds.remaining == [
  500.         [
  501.             (0, 2),
  502.             (2, 2)]]:
  503.         raise AssertionError
  504.     if not ds.active == [
  505.         [
  506.             (4, 2),
  507.             (6, 2)]]:
  508.         raise AssertionError
  509.     sd.got_piece(0, 4, 'ab')
  510.     if not events == [
  511.         'requested',
  512.         ('request', 0, 2, 2)]:
  513.         raise AssertionError
  514.     del events[:]
  515.     if not ds.remaining == [
  516.         [
  517.             (0, 2)]]:
  518.         raise AssertionError
  519.     if not ds.active == [
  520.         [
  521.             (2, 2),
  522.             (6, 2)]]:
  523.         raise AssertionError
  524.  
  525.  
  526. def test_got_have_single():
  527.     ds = DummyStorage([
  528.         [
  529.             (0, 2)]])
  530.     events = []
  531.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  532.     sd = d.make_download(DummyConnection(events))
  533.     if not events == []:
  534.         raise AssertionError
  535.     if not ds.remaining == [
  536.         [
  537.             (0, 2)]]:
  538.         raise AssertionError
  539.     if not ds.active == [
  540.         []]:
  541.         raise AssertionError
  542.     sd.got_unchoke()
  543.     if not events == []:
  544.         raise AssertionError
  545.     if not ds.remaining == [
  546.         [
  547.             (0, 2)]]:
  548.         raise AssertionError
  549.     if not ds.active == [
  550.         []]:
  551.         raise AssertionError
  552.     sd.got_have(0)
  553.     if not events == [
  554.         'got have',
  555.         'interested',
  556.         'requested',
  557.         ('request', 0, 0, 2)]:
  558.         raise AssertionError
  559.     del events[:]
  560.     if not ds.remaining == [
  561.         []]:
  562.         raise AssertionError
  563.     if not ds.active == [
  564.         [
  565.             (0, 2)]]:
  566.         raise AssertionError
  567.     sd.disconnected()
  568.     if not events == [
  569.         'lost have']:
  570.         raise AssertionError
  571.  
  572.  
  573. def test_choke_clears_active():
  574.     ds = DummyStorage([
  575.         [
  576.             (0, 2)]])
  577.     events = []
  578.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  579.     sd1 = d.make_download(DummyConnection(events))
  580.     sd2 = d.make_download(DummyConnection(events))
  581.     if not events == []:
  582.         raise AssertionError
  583.     if not ds.remaining == [
  584.         [
  585.             (0, 2)]]:
  586.         raise AssertionError
  587.     if not ds.active == [
  588.         []]:
  589.         raise AssertionError
  590.     sd1.got_unchoke()
  591.     sd1.got_have(0)
  592.     if not events == [
  593.         'got have',
  594.         'interested',
  595.         'requested',
  596.         ('request', 0, 0, 2)]:
  597.         raise AssertionError
  598.     del events[:]
  599.     if not ds.remaining == [
  600.         []]:
  601.         raise AssertionError
  602.     if not ds.active == [
  603.         [
  604.             (0, 2)]]:
  605.         raise AssertionError
  606.     sd2.got_unchoke()
  607.     sd2.got_have(0)
  608.     if not events == [
  609.         'got have']:
  610.         raise AssertionError
  611.     del events[:]
  612.     if not ds.remaining == [
  613.         []]:
  614.         raise AssertionError
  615.     if not ds.active == [
  616.         [
  617.             (0, 2)]]:
  618.         raise AssertionError
  619.     sd1.got_choke()
  620.     if not events == [
  621.         'interested',
  622.         'requested',
  623.         ('request', 0, 0, 2),
  624.         'not interested']:
  625.         raise AssertionError
  626.     del events[:]
  627.     if not ds.remaining == [
  628.         []]:
  629.         raise AssertionError
  630.     if not ds.active == [
  631.         [
  632.             (0, 2)]]:
  633.         raise AssertionError
  634.     sd2.got_piece(0, 0, 'ab')
  635.     if not events == [
  636.         'complete',
  637.         'not interested']:
  638.         raise AssertionError
  639.     del events[:]
  640.     if not ds.remaining == [
  641.         []]:
  642.         raise AssertionError
  643.     if not ds.active == [
  644.         []]:
  645.         raise AssertionError
  646.  
  647.  
  648. def test_endgame():
  649.     ds = DummyStorage([
  650.         [
  651.             (0, 2)],
  652.         [
  653.             (0, 2)],
  654.         [
  655.             (0, 2)]], True, 3)
  656.     events = []
  657.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 10, 15, 3, Measure(15), 10)
  658.     ev1 = []
  659.     ev2 = []
  660.     ev3 = []
  661.     ev4 = []
  662.     sd1 = d.make_download(DummyConnection(ev1))
  663.     sd2 = d.make_download(DummyConnection(ev2))
  664.     sd3 = d.make_download(DummyConnection(ev3))
  665.     sd1.got_unchoke()
  666.     sd1.got_have(0)
  667.     if not ev1 == [
  668.         'interested',
  669.         ('request', 0, 0, 2)]:
  670.         raise AssertionError
  671.     del ev1[:]
  672.     sd2.got_unchoke()
  673.     sd2.got_have(0)
  674.     sd2.got_have(1)
  675.     if not ev2 == [
  676.         'interested',
  677.         ('request', 1, 0, 2)]:
  678.         raise AssertionError
  679.     del ev2[:]
  680.     sd3.got_unchoke()
  681.     sd3.got_have(0)
  682.     sd3.got_have(1)
  683.     sd3.got_have(2)
  684.     if not ev3 == [
  685.         'interested',
  686.         ('request', 2, 0, 2),
  687.         ('request', 0, 0, 2),
  688.         ('request', 1, 0, 2)] or ev3 == [
  689.         'interested',
  690.         ('request', 2, 0, 2),
  691.         ('request', 1, 0, 2),
  692.         ('request', 0, 0, 2)]:
  693.         raise AssertionError
  694.     del ev3[:]
  695.     if not ev2 == [
  696.         ('request', 0, 0, 2)]:
  697.         raise AssertionError
  698.     del ev2[:]
  699.     sd2.got_piece(0, 0, 'ab')
  700.     if not ev1 == [
  701.         ('cancel', 0, 0, 2),
  702.         'not interested']:
  703.         raise AssertionError
  704.     del ev1[:]
  705.     if not ev2 == []:
  706.         raise AssertionError
  707.     if not ev3 == [
  708.         ('cancel', 0, 0, 2)]:
  709.         raise AssertionError
  710.     del ev3[:]
  711.     sd3.got_choke()
  712.     if not ev1 == []:
  713.         raise AssertionError
  714.     if not ev2 == []:
  715.         raise AssertionError
  716.     if not ev3 == []:
  717.         raise AssertionError
  718.     sd3.got_unchoke()
  719.     if not ev3 == [
  720.         ('request', 2, 0, 2),
  721.         ('request', 1, 0, 2)] or ev3 == [
  722.         ('request', 1, 0, 2),
  723.         ('request', 2, 0, 2)]:
  724.         raise AssertionError
  725.     del ev3[:]
  726.     if not ev1 == []:
  727.         raise AssertionError
  728.     if not ev2 == []:
  729.         raise AssertionError
  730.     sd4 = d.make_download(DummyConnection(ev4))
  731.     sd4.got_have_bitfield([
  732.         True,
  733.         True,
  734.         True])
  735.     if not ev4 == [
  736.         'interested']:
  737.         raise AssertionError
  738.     del ev4[:]
  739.     sd4.got_unchoke()
  740.     if not ev4 == [
  741.         ('request', 2, 0, 2),
  742.         ('request', 1, 0, 2)] or ev4 == [
  743.         ('request', 1, 0, 2),
  744.         ('request', 2, 0, 2)]:
  745.         raise AssertionError
  746.     if not ev1 == []:
  747.         raise AssertionError
  748.     if not ev2 == []:
  749.         raise AssertionError
  750.     if not ev3 == []:
  751.         raise AssertionError
  752.  
  753.  
  754. def test_stops_at_backlog_endgame():
  755.     ds = DummyStorage([
  756.         [
  757.             (2, 2),
  758.             (0, 2)],
  759.         [
  760.             (2, 2),
  761.             (0, 2)],
  762.         [
  763.             (0, 2)]], True, 3)
  764.     events = []
  765.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 3, 15, 3, Measure(15), 10)
  766.     ev1 = []
  767.     ev2 = []
  768.     ev3 = []
  769.     sd1 = d.make_download(DummyConnection(ev1))
  770.     sd2 = d.make_download(DummyConnection(ev2))
  771.     sd3 = d.make_download(DummyConnection(ev3))
  772.     sd1.got_unchoke()
  773.     sd1.got_have(0)
  774.     if not ev1 == [
  775.         'interested',
  776.         ('request', 0, 0, 2),
  777.         ('request', 0, 2, 2)]:
  778.         raise AssertionError
  779.     del ev1[:]
  780.     sd2.got_unchoke()
  781.     sd2.got_have(0)
  782.     if not ev2 == []:
  783.         raise AssertionError
  784.     sd2.got_have(1)
  785.     if not ev2 == [
  786.         'interested',
  787.         ('request', 1, 0, 2),
  788.         ('request', 1, 2, 2)]:
  789.         raise AssertionError
  790.     del ev2[:]
  791.     sd3.got_unchoke()
  792.     sd3.got_have(2)
  793.     if not ev2 == [
  794.         ('request', 0, 0, 2)] or ev2 == [
  795.         ('request', 0, 2, 2)]:
  796.         raise AssertionError
  797.     n = ev2[0][2]
  798.     del ev2[:]
  799.     sd1.got_piece(0, n, 'ab')
  800.     if not ev1 == []:
  801.         raise AssertionError
  802.     if not ev2 == [
  803.         ('cancel', 0, n, 2),
  804.         ('request', 0, 2 - n, 2)]:
  805.         raise AssertionError
  806.  
  807.